﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Data;
using LeagueOfRila.View;
using Microsoft.Xna.Framework;
using System.Threading;

namespace LeagueOfRila
{
    public class Animation
    {
        public static Dictionary<String, Texture2D> textures = new Dictionary<String, Texture2D>();
        public int currentStep = 0;
        public int maxStep = 0;
        public int stepTimer = 0;
        public int spriteX;
        public int spriteY;
        public int spriteWidth;
        public Player player;
        public int spriteHeight;
        public List<string> posSteps = new List<string>();
        public String type;
        public int posx = 0;
        public int posy = 0;
        public int mapX = 0;
        public int mapY = 0;
        public int timeAnim = 0;
        public int timeDisplayAnim = 0;
        public Thread timerAnimation ;
        public bool animationStarted = false;
        public bool animationFinished = false;
        public Thread displayAnim;
        public int damage;

        public Animation(String type, Player player,int mapX,int mapY)
        {
            this.player = player;
            this.type = type;
            this.posx = player.posX;
            this.posy = player.posY;

            if (Client.player.pseudo != player.pseudo)
            {
                this.mapX = mapX;
                this.mapY = mapY;    
            }
            this.posx = this.posx + this.mapX;
            this.posy = this.posy + this.mapY;
            switch (type)
            {
                case "sword":
                    maxStep = 3;
                    spriteX = 32;
                    spriteY = 48;
                    spriteWidth = 42;
                    spriteHeight = 42;
                    switch (player.character.name)
                    {
                        case "War":
                            timeAnim = 1500;
                            timeDisplayAnim = 1500;
                            break;
                        case "Matthieu":
                            timeAnim = 500;
                            timeDisplayAnim = 500;
                            break;
                        case "Priest":
                            timeAnim = 1500;
                            timeDisplayAnim = 1500;
                            break;
                    }
                    
                    posSteps.Add(String.Concat("1/", player.posX.ToString(), "/", player.posY.ToString(), "/", player.orientation.ToString()));
                    break;
                case "fire":
                    maxStep = 3;
                    spriteX = 32;
                    spriteY = 48;
                    spriteWidth = 42;
                    spriteHeight = 42;
                    posSteps.Add(String.Concat("1/", player.posX.ToString(), "/", player.posY.ToString(), "/", player.orientation.ToString()));
                    break;
                case "confession":
                    maxStep = 4;
                    spriteX = 32;
                    spriteY = 48;
                    spriteWidth = 192;
                    spriteHeight = 192;
                    timeAnim = 2000;
                    timeDisplayAnim = 6000;
                    break;
                case "execution":
                    maxStep = 4;
                    spriteX = 32;
                    spriteY = 48;
                    spriteWidth = 192;
                    spriteHeight = 192;
                    timeAnim = 2000;
                    timeDisplayAnim = 6000;
                    break;
                case "circlefire":
                    maxStep = 4;
                    spriteX = 32;
                    spriteY = 48;
                    spriteWidth = 192;
                    spriteHeight = 192;
                    timeAnim = 2000;
                    timeDisplayAnim = 6000;
                    posSteps.Add(String.Concat("1/", player.posX.ToString(), "/", player.posY.ToString(), "/", player.orientation.ToString()));
                    break;
                case "boltfire":
                    maxStep = 4;
                    spriteX = 32;
                    spriteY = 48;
                    spriteWidth = 192;
                    spriteHeight = 192;
                    timeAnim = 500;
                    timeDisplayAnim = 6000;
                    posSteps.Add(String.Concat("1/", player.posX.ToString(), "/", player.posY.ToString(), "/", player.orientation.ToString()));
                    break;
                case "speed":
                    timeAnim = 500;
                    timeDisplayAnim = 6000;
                    break;
                case "damage":

                    timeAnim = 1000;
                    timeDisplayAnim = 1000;  
                    break;
            }
            
        }

        public void DisplayAnimation(GameView gameview)
        {
            switch (type)
            {
                case "sword":
                    DisplaySword(gameview);
                    break;
                case "circlefire":
                    DisplayCircleFire(gameview);
                    break;
                case "boltfire":
                    DisplayBoltFire(gameview);
                    break;
                case "confession":
                    DisplayConfession(gameview);
                    break;
                case "execution":
                    DisplayExecution(gameview);
                    break;
                case "speed":
                    DisplaySpeed(gameview);
                    break;
                case "damage":
                    DisplayDamage(gameview);
                    break;
            }
            
        }

        public void DisplayDamage(GameView gameview)
        {
            posy = this.player.posY + this.mapY - 50;
            posx = this.player.posX + this.mapX ;
            animationTimeElapsed();

            if (!animationFinished)
                gameview.DrawFont(damage.ToString(), new Vector2(posx, posy), Color.Red);
        
        }

        public void DisplaySword(GameView gameview)
        {
            this.addStep();
            switch(this.player.orientation)
            {
                case 0:
                    posy = this.player.posY + this.mapY + 20;
                    posx = this.player.posX + this.mapX + 6;
                    break;

                case 1:
                    posx = this.player.posX + this.mapX - 15;
                    break;

                case 2:
                    posx = this.player.posX + this.mapX + 15;
                    break;

                case 3:
                    posy = this.player.posY + this.mapY - 1;
                    posx = this.player.posX + this.mapX - 8;
                    break;
            }

            animationTimeElapsed();

            if (!animationFinished)
               gameview.DrawImage(textures[this.type], new Rectangle(posx, posy, this.player.character.spriteX, this.player.character.spriteY), new Rectangle(this.currentStep * this.player.character.spriteX, this.player.orientation * this.player.character.spriteY, this.spriteX, this.spriteY));

            
        }
        public void DisplayCircleFire(GameView gameview)
        {
            
            this.addStep();
            posy = this.player.posY + this.mapY - 75;
            posx = this.player.posX + this.mapX - 80;

            animationTimeElapsed();

            if (!animationFinished)
            {

                gameview.DrawImage(textures[this.type], new Rectangle(posx, posy, this.spriteWidth, this.spriteHeight), new Rectangle(0, 0, this.spriteWidth, this.spriteHeight));
                gameview.DrawOtherCharacters();
            }

        }
        public void DisplayBoltFire(GameView gameview)
        {
            this.addStep();
            int modifSpriteHeight = this.spriteHeight;
            int modifSpriteWidth = this.spriteWidth;

            switch (this.player.orientation)
            {
                case 0: //bas
                    posy = this.player.posY + this.mapY - 110;
                    posx = this.player.posX + this.mapX - 90;
                    modifSpriteHeight = 600;
                    break;

                case 1: //gauche
                    posy = this.player.posY + this.mapY - 70;
                    posx = this.player.posX + this.mapX - 435;
                    modifSpriteWidth = 600;
                    break;

                case 2: //droite
                    posy = this.player.posY + this.mapY - 70;
                    posx = this.player.posX + this.mapX - 180;
                    modifSpriteWidth = 600;
                    break;

                case 3: //haut
                    posy = this.player.posY + this.mapY - 400;
                    posx = this.player.posX + this.mapX - 90;
                    modifSpriteHeight = 600;
                    break;
            }


            animationTimeElapsed();

            if (!animationFinished)
            {

                gameview.DrawImage(textures[this.type], new Rectangle(posx, posy, modifSpriteWidth, modifSpriteHeight), new Rectangle(0, 0, this.spriteWidth, this.spriteHeight));
                gameview.DrawOtherCharacters();
            }
        }

        public void DisplayConfession(GameView gameview)
        {

            this.addStep();
            posy = this.player.posY + this.mapY - 75;
            posx = this.player.posX + this.mapX - 80;

            animationTimeElapsed();

            if (!animationFinished)
            {

                gameview.DrawImage(textures[this.type], new Rectangle(posx, posy, this.spriteWidth, this.spriteHeight), new Rectangle(0, 0, this.spriteWidth, this.spriteHeight));
                gameview.DrawOtherCharacters();
            }
        }
        public void DisplayExecution(GameView gameview)
        {
            this.addStep();
            switch (this.player.orientation)
            {
                case 0:
                    posy = this.player.posY + this.mapY + 20;
                    posx = this.player.posX + this.mapX + 6;
                    break;

                case 1:
                    posx = this.player.posX + this.mapX - 15;
                    break;

                case 2:
                    posx = this.player.posX + this.mapX + 15;
                    break;

                case 3:
                    posy = this.player.posY + this.mapY - 1;
                    posx = this.player.posX + this.mapX - 8;
                    break;
            }

            animationTimeElapsed();

            if (!animationFinished)
                gameview.DrawImage(textures[this.type], new Rectangle(posx, posy, this.player.character.spriteX, this.player.character.spriteY), new Rectangle(this.currentStep * this.player.character.spriteX, this.player.orientation * this.player.character.spriteY, this.spriteX, this.spriteY));

        }

        public void DisplaySpeed(GameView gameview)
        {
            animationTimeElapsed();

            if (!animationFinished)
            {
                switch (Client.player.orientation)
                {
                    case 0:
                        gameview.GetModel().GoDown();
                        gameview.GetModel().GoDown();
                        gameview.GetModel().GoDown();
                        gameview.GetModel().GoDown();
                        break;
                    case 1:
                        gameview.GetModel().GoLeft();
                        gameview.GetModel().GoLeft();
                        gameview.GetModel().GoLeft();
                        gameview.GetModel().GoLeft();
                        break;
                    case 2:
                        gameview.GetModel().GoRight();
                        gameview.GetModel().GoRight();
                        gameview.GetModel().GoRight();
                        gameview.GetModel().GoRight();
                        break;
                    case 3:
                        gameview.GetModel().GoUp();
                        gameview.GetModel().GoUp();
                        gameview.GetModel().GoUp();
                        gameview.GetModel().GoUp();
                        break;
                }
                
                gameview.GetModel().tellServerCharInfos();
            }
        }

        public void addStep()
        {
            if (stepTimer == 10)
            {
                if (this.currentStep < maxStep-1)
                {
                    this.currentStep++;
                }
                else
                {
                    this.currentStep = 0;
                }
                stepTimer = 0;
            }
            stepTimer++;
        }

        public void animationTimeElapsed ()
        {
            
            if (!animationStarted)
            {
                timerAnimation = new Thread(() => {
                    animationFinished = false;
                    Thread.Sleep(timeAnim); 
                    animationStarted = true;
                    animationFinished = true; });
                timerAnimation.Start();
                //animationStarted = true;
            }
           
        }
    }
}
